package com.evil.activiti.listener;

import cn.hutool.core.collection.ListUtil;
import com.alibaba.fastjson.JSON;
import com.evil.activiti.enums.EventTypeEnum;
import com.evil.activiti.util.ActivityUtil;
import com.evil.application.api.RemoteApplicationProcessNodeService;
import com.evil.common.account.dto.user.UserEnterpriseDTO;
import com.evil.common.application.dto.order.node.OrderNodeReqDTO;
import com.evil.common.core.util.StreamUtil;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 节点开始监听器
 *
 * @author liyang
 * @date 2022-08-08 00:00
 */
@Slf4j
@Component("FlowStartListener")
@AllArgsConstructor
public class FlowStartListener implements ExecutionListener {

    private final RemoteApplicationProcessNodeService remoteApplicationProcessNodeService;

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void notify(DelegateExecution execution) {
        String eventName = execution.getEventName();
        Long orderId = execution.getVariable(ActivityUtil.getProcessOrderIdKey(), Long.class);
        FlowElement flowElement = execution.getCurrentFlowElement();
        Map<String, Object> variables = execution.getVariables();
        log.info("【节点开始监听器】，execution.getEventName参数：{}", eventName);
        log.info("【节点开始监听器】，订单id:{}", orderId);
        log.info("【节点开始监听器】，节点id：{}, 节点name:{}", flowElement.getId(), flowElement.getName());
        log.info("【节点开始监听器】，execution.getVariables参数：{}", JSON.toJSONString(variables));

        // 开始事件
        if (EventTypeEnum.START.getEvent().equals(eventName)) {
            if (flowElement instanceof UserTask) {
                UserTask userTask = (UserTask) flowElement;
                Long nodeId = ActivityUtil.restoreFlowNodeId(userTask.getId());
                // 获取节点负责人
                OrderNodeReqDTO orderNodeReqDTO = new OrderNodeReqDTO(orderId, nodeId);
                List<UserEnterpriseDTO> nodeHandlers = remoteApplicationProcessNodeService.getNodeHandlers(orderNodeReqDTO);
                log.info("【节点开始监听器】，节点所有负责人：{}", nodeHandlers);

                Map<String, List<UserEnterpriseDTO>> groupAssignees = new HashMap<>();
                if (ActivityUtil.checkLoopCharacteristics(userTask.getLoopCharacteristics())) {
                    // 审批会签节点 （目前没有逐级审批，一人一组）
                    execution.setVariableLocal(ActivityUtil.IS_COUNTERSIGN, true);
                    for (int i = 0; i < nodeHandlers.size(); i++) {
                        groupAssignees.put(String.valueOf(i + 1), ListUtil.toList(nodeHandlers.get(i)));
                    }
                } else {
                    // 普通用户节点 （全部人同一个组）
                    execution.setVariableLocal(ActivityUtil.IS_COUNTERSIGN, false);
                    groupAssignees.put("1", nodeHandlers);
                }

                Map<String, Set<String>> groupIdentityLinks = StreamUtil.transMapV(groupAssignees, v -> new HashSet<>(ActivityUtil.toActivitiLoginUsers(v)));

                userTask.setCustomUserIdentityLinks(groupIdentityLinks);
                // 补充流程默认值
                execution.setVariable(ActivityUtil.nrOfCompletedInstances, 0);
                execution.setVariable(ActivityUtil.nrOfInstances, groupIdentityLinks.size());
            }
        }
    }
}
